package com.jojo.rateLimiter;

import java.util.concurrent.atomic.AtomicInteger;

/**
 * 固定窗口算法
 *
 * @author hpl
 * @since 2024/12/12
 */
public class FixedWindow {

    // 限制的时间窗口大小，单位是秒
    private final int windowSizeInSeconds;

    // 每个窗口内允许的最大请求数
    private final int maxRequests;

    // 当前窗口内的请求计数
    private final AtomicInteger requestCount = new AtomicInteger(0);

    // 上次请求时间
    private long lastRequestTimestamp;

    public FixedWindow(int windowSizeInSeconds, int maxRequests) {
        this.windowSizeInSeconds = windowSizeInSeconds;
        this.maxRequests = maxRequests;
        this.lastRequestTimestamp = System.currentTimeMillis() / 1000; // 初始化为当前时间的秒数
    }

    /**
     * 判断是否允许请求
     *
     * @return true 如果请求被允许，false 如果请求被拒绝
     */
    public boolean allowRequest() {
        long currentTimestamp = System.currentTimeMillis() / 1000; // 当前时间的秒数

        // 如果当前时间窗口已结束（超过指定时间窗口）
        if (currentTimestamp > lastRequestTimestamp + windowSizeInSeconds) {
            // 重置请求计数
            lastRequestTimestamp = currentTimestamp;
            requestCount.set(0);
        }

        // 判断请求是否超过最大限制
        if (requestCount.get() < maxRequests) {
            // 允许请求，通过时增加请求计数
            requestCount.incrementAndGet();
            return true;
        }

        // 超过最大请求数，拒绝请求
        return false;
    }

    public static void main(String[] args) {
        // 创建一个固定窗口限流器，窗口大小为1秒，最大请求数为5
        FixedWindow rateLimiter = new FixedWindow(1, 5);

        // 模拟连续请求
        for (int i = 1; i <= 10; i++) {
            if (rateLimiter.allowRequest()) {
                System.out.println("Request " + i + " allowed");
            } else {
                System.out.println("Request " + i + " denied");
            }

            // 暂停100毫秒，以模拟请求间的间隔
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}
